<?php
/**
 * 店铺
 * 
 * Created  : 2011-05-03
 * Modified : 2011-05-03
 * @author  : 陈立强
 */
class Shop
{
	
	public static $cfg = null;
	public static $cfgName = 'build/shop';

	/**
	 * 创建店铺
	 * @param int $uid
	 * @param char $area 区域编号（字母A-I）
	 * @param int $street_id
	 * @return array
	 */
	public static function create($uid)
	{
		global $DB, $L, $G;

		$sql = 'SELECT shop_id FROM user_shop WHERE uid='.$uid;
		$record = $DB->getValue($sql);
		if ($record) {
			return array(
				'val' => false,
				'msg' => $L['user_shop_had_created']
			);
		}
		
		$DB->beginTransaction();
		
		$now = time();
		$data = array(
			'uid'					=> $uid,
			'pop_val'				=> 0,
			'clean_val'				=> $G['shop_init_clean_val'],
			'depot_space'			=> $G['shop_depot_init_space'],
			'queue_space'			=> $G['init_queue_space'],
			'sale_space'			=> $G['init_sale_space'],
			'create_time'			=> $now,
			'last_get_guest_time'	=> $now - $G['shop_queue_update_time'],
			'rubbish_num'			=> 0,// 垃圾数
			'last_rand_rubbish_time'=> $now,// 上次随机到垃圾的时间
			'ok_guest_mood'			=> 0,// 已完成顾客总心情值
			'ok_guest_num'			=> 0,// 已完成顾客总数量
			'ok_item_quality'		=> 0,// 平均品质
			// 已完成顾客总心情值除以顾客总数量得到平均心情,即口碑
		);
		$ret = $shop_id = $DB->insert('user_shop', $data);
		
		// 初始化店铺排队区的数据 
		if ($shop_id) {
			for ($i=0; $i<$G['init_queue_space']; $i++) {
				$data = array(
					'uid'		=> $uid,
					'pos'		=> $i+1,
					'lvl'		=> 0,
					'now_guest'	=> 0,
					'guest_lvl'	=> 0,
					'guest_mood'=> 0,
					'off_time'	=> 0,
					'last_reduce_mood_time'	=> 0,
				);
				$ret = $DB->insert('user_shop_queue_area', $data);
				if (!$ret) {
					break;
				}
			}
		}
		
		// 初始化店铺销售区的数据 
		if ($ret) {
			for ($i=0; $i<$G['init_sale_space']; $i++) {
				$data = array(
					'uid'			=> $uid,
					'pos'			=> $i+1,
					'lvl'			=> 0,
					'now_guest'		=> 0,
					'guest_lvl'		=> 0,
					'guest_mood'	=> 0,
					'need_item_type'=> 0,
					'now_item'		=> 0,
					'like_item'		=> 0,
					'quality'		=> 0,
					'main_mat_quality'=> 0,
					'need_service'	=> 0,
					'last_srv_time'	=> 0,
					'now_coin'		=> 0,
					'state'			=> 0,
					'off_time'		=> 0,
					'last_reduce_mood_time'	=> 0,
				);
				$ret = $DB->insert('user_shop_sale_area', $data);
				if (!$ret) {
					break;
				}
			}
		}
		

		if ($ret) {
			$DB->commit();
		} else {
			$DB->rollBack();
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_create', $str);
		}

		return $ret;
	}
	
	/**
	 * 获取店铺信息
	 * @param int $uid
	 */
	public static function getInfo($uid, $to_uid=null)
	{
		global $DB, $L, $G;
		
		$to_uid = (int)$to_uid;
		if ($to_uid) {
			$uid = $to_uid;
		}
		
		$sql = 'SELECT * FROM user_shop WHERE uid='.$uid;
		$shop = $DB->getValue($sql);
		
		$shop['avg_quality'] = ($shop['ok_guest_num']==0) 
					? 0 
					: floor($shop['ok_item_quality']/$shop['ok_guest_num']);
					
		$shop['avg_mood'] = ($shop['ok_guest_num']==0) 
					? 0 
					: floor($shop['ok_guest_mood']/$shop['ok_guest_num']);
								
		return $shop;
	}
	
	/**
	 * 扩建一个排队空位
	 * @param int $uid
	 */
	public static function addQueuePos($uid)
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT shop_id,pop_val,queue_space FROM user_shop WHERE uid='.$uid;
		$shop = $DB->getValue($sql);
		
		// 人气值是否达到
		if ($shop['pop_val'] < $G['shop_queue_space'][$shop['queue_space']]) {
			return array(
				'val' => false,
				'msg' => $L['pop_val_not_enough_to_add_pos']
			);
		}
	
		// 金钱是否足够
		$needCoin = $G['shop_queue_space_coin'][$shop['queue_space']];
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($needCoin > $coin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		$DB->beginTransaction();
		
		// 更新店铺排队区空位数
		$sql = 'UPDATE user_shop SET queue_space=queue_space+1 WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		// 扣除金线
		if ($ret) {
			$sql = 'UPDATE user set coin=coin-'.$needCoin.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		if ($ret) {
			$data = array(
				'uid'		=> $uid,
				'pos'		=> $shop['queue_space']+1,
				'lvl'		=> 0,
				'now_guest'	=> 0,
				'state'		=> 0,
				'guest_lvl'	=> 0,
				'guest_mood'=> 0,
				'off_time'	=> 0,
				'last_reduce_mood_time'	=> 0,
			);
			$ret = $DB->insert('user_shop_queue_area', $data);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			
			$DB->commit();
			$result['data'] = array(
				
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L[''];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_add_queue_pos', $str);
		}

		return $result;
	}
	
	/**
	 * 升级排队区空位
	 * @param int $uid
	 * @param int $pos
	 */
	public static function lvlUpQueuePos($uid, $pos)
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT lvl FROM user_shop_queue_area WHERE uid='.$uid.' and pos='.(int)$pos;
		$lvl = $DB->getValue($sql);
		if ($lvl === false) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		if (!isset($G['shop_queue_space_lvl'][$lvl])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		$sql = 'SELECT shop_id,pop_val FROM user_shop WHERE uid='.$uid;
		$shop = $DB->getValue($sql);
		
		// 人气值是否达到
		if ($shop['pop_val'] < $G['shop_queue_space_lvl'][$lvl]) {
			return array(
				'val' => false,
				'msg' => $L['pop_val_not_enough_to_add_pos']
			);
		}
		
		// 金钱是否足够
		$needCoin = $G['shop_queue_space_lvl_coin'][$lvl];
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($needCoin > $coin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		$DB->beginTransaction();
		
		// 扣除金线
		$sql = 'UPDATE user set coin=coin-'.$needCoin.' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		if ($ret) {
			$sql = 'UPDATE user_shop_queue_area SET lvl=lvl+1 WHERE uid='.$uid.' and pos='.(int)$pos;
			$ret = $DB->exeSql($sql);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'depot_id' => $ret
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_lvl_up_queue_pos', $str);
		}

		return $result;
	}
	
	/**
	 * 扩建一个销售空位
	 * @param int $uid
	 */
	public static function addSalePos($uid)
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT shop_id,pop_val,sale_space FROM user_shop WHERE uid='.$uid;
		$shop = $DB->getValue($sql);
		
		// 人气值是否达到
		if ($shop['pop_val'] < $G['shop_sale_space'][$shop['sale_space']]) {
			return array(
				'val' => false,
				'msg' => $L['pop_val_not_enough_to_add_pos']
			);
		}
	
		// 金钱是否足够
		$needCoin = $G['shop_sale_space_coin'][$shop['sale_space']];
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($needCoin > $coin) {
			return array(
				'val' => false,
				'sql' => $sql,
				'msg' => $L['coin_not_enough']
			);
		}
		
		$DB->beginTransaction();
		
		// 更新店铺销售区空位数
		$sql = 'UPDATE user_shop SET sale_space=sale_space+1 WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		// 扣除金线
		if ($ret) {
			$sql = 'UPDATE user set coin=coin-'.$needCoin.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		if ($ret) {
			$data = array(
				'uid'				=> $uid,
				'pos'				=> $shop['sale_space']+1,
				'lvl'				=> 0,
				'now_guest'			=> 0,
				'guest_lvl'			=> 0,
				'guest_mood'		=> 0,
				'need_item_type'	=> 0,
				'now_item'			=> 0,
				'like_item'			=> 0,
				'quality'			=> 0,
				'main_mat_quality'	=> 0,
				'need_service'		=> 0,
				'last_srv_time'		=> 0,
				'now_coin'			=> 0,
				'state'				=> 0,
				'off_time'			=> 0,
				'rubbish'			=> 0,
				'last_reduce_mood_time'	=> 0,
			);
			$ret = $DB->insert('user_shop_sale_area', $data);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_add_sale_pos', $str);
		}

		return $result;
	}
	
	/**
	 * 升级销售区空位
	 * @param int $uid
	 * @param int $pos
	 */
	public static function lvlUpSalePos($uid, $pos)
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT lvl FROM user_shop_sale_area WHERE uid='.$uid.' and pos='.(int)$pos;
		$lvl = $DB->getValue($sql);
		
		if (!isset($G['shop_sale_space_lvl'][$lvl])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		$sql = 'SELECT shop_id,pop_val FROM user_shop WHERE uid='.$uid;
		$shop = $DB->getValue($sql);
		
		// 人气值是否达到
		if ($shop['pop_val'] < $G['shop_sale_space_lvl'][$lvl]) {
			return array(
				'val' => false,
				'msg' => $L['pop_val_not_enough_to_add_pos']
			);
		}
		
		// 金钱是否足够
		$needCoin = $G['shop_sale_space_lvl_coin'][$lvl];
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($needCoin > $coin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		$DB->beginTransaction();
		
		// 扣除金线
		$sql = 'UPDATE user set coin=coin-'.$needCoin.' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		if ($ret) {
			$sql = 'UPDATE user_shop_sale_area SET lvl=lvl+1 WHERE uid='.$uid.' and pos='.(int)$pos;
			$ret = $DB->exeSql($sql);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'depot_id' => $ret
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_lvl_up_sale_pos', $str);
		}

		return $result;
	}
	
	/**
	 * 扩展店铺仓库的空位
	 * @param int $uid
	 */
	public static function addDepotSpace($uid)
	{
		global $DB, $L, $G;
		$sql = 'SELECT pop_val,depot_space FROM user_shop WHERE uid='.$uid;
		$record = $DB->getValue($sql);
		$canExtend = false;
		// 判断人气值是否达到
		foreach ($G['shop_depot'] as $num=>$pop_val) {
			if ($num > $record['depot_space'] && $pop_val <= $record['pop_val']) {
				$canExtend = true;
				break;
			}
		}
		// 不能扩展
		if (!$canExtend) {
			return array(
				'val' => false,
				'msg' => $L['pop_val_not_enough_to_add_pos']
			);
		}
		
		// 金钱是否足够
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($coin < $G['shop_depot_add_space_coin']) {
			return array(
				'val' => false,
				'msg' => $L['shop_depot_extend_coin_not_enough']
			);
		}
		
		$DB->beginTransaction();
		
		// 扣除金钱
		$sql = 'UPDATE user set coin=coin-'.$G['shop_depot_add_space_coin'].' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		if ($ret) {
			$sql = 'UPDATE user_shop set depot_space=depot_space+1 WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'depot_id' => $ret,
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_add_depot_space', $str);
		}

		return $result;
	}
	
	/**
	 * 排队区增加新顾客
	 * @param int $uid
	 * @param array $posInfo
	 */
	private static function addQueueGuest($uid, $posInfo)
	{
		global $DB, $L, $G;
		
		$now = time();
		
		$sql = 'SELECT * FROM user_shop WHERE uid='.$uid;
		$shop = $DB->getValue($sql);
		
		$DB->beginTransaction();
		
		$ret = false;
		
		$usqa_id = $posInfo['usqa_id'];
		// 随机生成一个顾客
		$guestCfg	= C('shop/guest');
		$guestId	= array_rand($guestCfg);
		$guest		= $guestCfg[$guestId];
		
		// 获取平均品质
		$avgQuality = ($shop['ok_guest_num']==0) 
					? 0 
					: floor($shop['ok_item_quality']/$shop['ok_guest_num']);
		foreach ($G['guest_lvl_avg_quality'] as $lvl=>$value) {
			if ($avgQuality<=$value) {
				$guestLvl = $lvl;
				break;
			}
		}
		
		if ($guestLvl>1) {
			$avgMood = ($shop['ok_guest_num']==0) 
							? 0 
							: ($shop['ok_guest_mood']/$shop['ok_guest_num']);
			$rand = getRandResult($avgMood, $G['guest_max_mood']);
			if (!$rand) {
				$guestLvl--;
			}
		}
		// 计算初始心情
		$guestMood = $G['guest_init_mood'] + $G['shop_queue_area_add_mood'][$posInfo['lvl']];
		
		// 实际当前心情值为初始心情扣除到来时间到现在减少差后的实际心情值
		// 垃圾影响的心情值
		// 分钟数
		$minitues = floor(($now - $posInfo['comein_time'])/60);
		$guestMood -=  $minitues * ($G['queue_reduce_mood'] + $shop['rubbish_num']);
		$guestMood -= $minitues * $shop['rubbish_num'];
		if ($guestMood < $G['guest_min_mood']) {
			$guestMood = $G['guest_min_mood'];
		} elseif ($guestMood>$G['guest_max_mood']) {
			$guestMood = $G['guest_max_mood'];
		}
		
		$data = array(
			'now_guest'	=> $guestId,
			'state'		=> 1,
			'guest_lvl' => $guestLvl,
			'guest_mood'=> $guestMood,
			'off_time'	=> $posInfo['off_time'],
			'last_reduce_mood_time'	=> $now,
		);
		
		$where = 'usqa_id='.$usqa_id;
		$ret = $DB->update('user_shop_queue_area', $data, $where);
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_add_queue_guest', $str);
		}

		return $result;
	}
	
	/**
	 * 获取排队区数据
	 * @param int $uid
	 * @param int $to_uid 获取他人的列表
	 */
	public static function getQueueList($uid, $to_uid=null)
	{
		global $DB, $L, $G;
		
		$now = time();

		$to_uid = (int)$to_uid;
		if ($to_uid) {
			$uid = $to_uid;
		}
		
		$usqaSql = 'SELECT * FROM user_shop_queue_area WHERE uid='.$uid;
		$usqaList = $DB->getList($usqaSql);
		if (!$usqaList) {
			return array(
				'val'	=> false,
				'msg'	=> $L['invalid_request'].$usqaSql
			);
		}
		
		
		$list = array();
		foreach ($usqaList as $k=>$item) {
			$list[$item['pos']] = $item;
		}
		ksort($list);
		
		// 店铺信息
		$sql = 'SELECT ok_guest_mood,ok_guest_num,rubbish_num,last_get_guest_time, queue_space'
				.' FROM user_shop WHERE uid='.$uid;
		$shopInfo = $DB->getValue($sql);
		if (!$shopInfo) {
			return array(
				'val'	=> false,
				'msg'	=> $L['invalid_request']
			);
		}
		// 上次顾客到来时间,程序假设为"当前运行时间"
		$assumeNow = $shopInfo['last_get_guest_time'];
//		echo date('Y-m-d H:i:s', $assumeNow);
//		echo "\n";
	
		$updateIds = array();
	
		// 上次新增顾客到现在时间间隔
		$intervalTime = $now - $assumeNow;
		// 间隔时间内可以新产生的最多顾客数量
		$addNum = floor($intervalTime/$G['shop_queue_update_time']);
		// 最多可以增加的顾客数不会超过总空位数
		$maxAddNum = min($addNum, $shopInfo['queue_space']);
//		var_dump($intervalTime);
		// 从上次顾客到来后的每个时间点的排队区情况
		for ($i=1; $i<=$addNum; $i++) {
			$assumeNow += $G['shop_queue_update_time'];
			if ($assumeNow > $now) break;
			$hour = (int)date('H', $assumeNow);
			// 凌晨时间不增加顾客
			if ($hour < 8) {
				$assumeNow = strtotime(date('Y-m-d H:0:0', $assumeNow).' +1 hours');
				continue;
			}
			$lastTime = $assumeNow;
			$sameTimeCnt = 0;
			// 找个空位,增加当前时段的顾客
			foreach ($list as $pos=>$v) {
				// 该时间点该位置顾客离开了
				if ($list[$pos]['off_time'] <= $assumeNow) {
					$list[$pos]['now_guest'] = 1;
					$list[$pos]['state'] = 99;
					$list[$pos]['off_time'] = $assumeNow + $G['queue_wait_time'];
					$list[$pos]['last_reduce_mood_time'] = $assumeNow;
					$list[$pos]['comein_time'] = $assumeNow;
					if (!in_array($v['usqa_id'], $updateIds)) {
						$updateIds[] = $v['usqa_id'];
					}
					$lastTime = $assumeNow;
//					echo $pos, ' ';
//					echo date('Y-m-d H:i:s', $assumeNow);
//					echo "\n";
					break;
				} elseif ($list[$pos]['now_guest'] == 0) {
					$list[$pos]['now_guest'] = 1;// 新顾客先假定是1
					$list[$pos]['state'] = 99;// 假定有顾客的状态
					$list[$pos]['off_time'] = $assumeNow + $G['queue_wait_time'];
					$list[$pos]['last_reduce_mood_time'] = $assumeNow;
					$list[$pos]['comein_time'] = $assumeNow;
					if (!in_array($v['usqa_id'], $updateIds)) {
						$updateIds[] = $v['usqa_id'];
					}
					$lastTime = $assumeNow;
//					echo $pos, ' ';
//					echo date('Y-m-d H:i:s', $assumeNow);
//					echo "\n";
					break;
				} else {
					// 当前位置有人啦,继续找下一个空位
					continue;
				}
			}
		}
		
		$DB->beginTransaction();
		
		// 更新上次顾客到来时间为最新时间
		if ($assumeNow > $now) {
//			echo "\n------------\n";
//			echo date('Y-m-d H:i:s', $assumeNow);
//			echo "\n";
			$assumeNow = strtotime(date('Y-m-d H:0:0'));
		}
//		echo date('Y-m-d H:i:s', $assumeNow);
//		echo "\n";
//		echo date('Y-m-d H:i:s', $assumeNow + $G['shop_queue_update_time']);
//		echo "\n";
//		exit;
		$sql = 'UPDATE user_shop SET last_get_guest_time='.$assumeNow
				.' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
	
		$spacePosList = array();
		$updateSql = '';
		foreach ($list as $pos=>$item) {
			if ($item['now_guest'] && $item['state'] == 99) {
				$DB->setTransactionState(false);
				self::addQueueGuest($uid, $item);
				$DB->setTransactionState(true);
				continue;
			}
			if ($list[$pos]['off_time'] <= $now) {
				$data = array(
					'now_guest'				=> 0,
					'state'					=> 0,
					'guest_lvl'				=> 0,
					'guest_mood'			=> 0,
					'off_time'				=> 0,
					'last_reduce_mood_time' => 0,
				);
				$ret = $DB->update('user_shop_queue_area', $data, 'usqa_id='.$item['usqa_id']);
				continue;
			}
			// 顾客心情值要减少
			$intervalTime = $now - $item['last_reduce_mood_time'];
			$minites = floor($intervalTime/60);// 上次扣除心情到现在间隔的分钟数
			// 减少心情数要考虑垃圾数量
			$reduceMoods = ($G['queue_reduce_mood'] + $shopInfo['rubbish_num']) * $minites;
			$reduceTime = $minites*60 + $item['last_reduce_mood_time'];
			$item['last_reduce_mood_time'] = $reduceTime;
			if (($item['guest_mood']-$G['guest_min_mood']) > $reduceMoods) {
				$item['guest_mood'] -= $reduceMoods;
			} else {
				$item['guest_mood'] = $G['guest_min_mood'];
			}
			$updateSql .= 'UPDATE user_shop_queue_area SET last_reduce_mood_time='.$reduceTime
						.', guest_mood='.$item['guest_mood']
						.' WHERE usqa_id='.$item['usqa_id'].';';
		}
	
		if ($updateSql != '') {
			$ret = $DB->exeSql($updateSql);
			$ret!==false && $ret = true;
		}
		
		$usqaList = $DB->getList($usqaSql);
		
		$list = array();
		foreach ($usqaList as $k=>$item) {
			$list[$item['pos']] = $item;
		}
		ksort($list);
		unset($usqaList);
		
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$nextGetGuestTime = $assumeNow + $G['shop_queue_update_time'];
			$result['data'] = array(
				'list' => $list,
				'next_refresh_time'=> $nextGetGuestTime
			);
		} else {
			$DB->rollBack();
			if (isset($result['msg'])) {
				$result['msg'] = $L['Failure_Update'];
			}
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_get_queue_list', $str);
		}
		
		return $result;
	}
	
	/**
	 * 将顾客从排队区拉到销售区
	 * @param int $uid
	 * @param int $queuePos 等待区被拉的顾客位置
	 * @param int $salePos 顾客被拉到销售区的位置 
	 */
	public static function moveQueue2sale($uid, $queuePos, $salePos)
	{
		global $DB, $L, $G;
		
		$now = time();
		
		// 等待区位置上是否有顾客
		$sql = 'SELECT * FROM user_shop_queue_area WHERE uid='.$uid.' and pos='.$queuePos.' and state=1';
		$usqa = $DB->getValue($sql);
		if (!$usqa) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 有已经过期的顾客要清空
		if ($usqa['off_time'] > 0 && $usqa['off_time'] <= $now) {
			$data = array(
				'now_guest'	=> 0,
				'state'		=> 0,
				'guest_lvl'	=> 0,
				'guest_mood'=> 0,
				'off_time'	=> 0,
				'last_reduce_mood_time'	=> 0,
			);
			$where = 'usqa_id ='.$usqa['usqa_id'];
			$ret = $DB->update('user_shop_queue_area', $data, $where);
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		// 销售区位置上是否有顾客
		$sql = 'SELECT * FROM user_shop_sale_area WHERE uid='.$uid.' and pos='.$salePos;
		$ussa = $DB->getValue($sql);
		// 空位未开启
		if (!$ussa) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 空位已经有顾客且未到时间
		if ($ussa['state']>0 && $ussa['off_time'] > $now) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		//-- 生成顾客的商品需求
		// 获取开启工坊的建筑
		$sql = 'SELECT class FROM make_building WHERE uid='.$uid;
		$list = $DB->getList($sql);
		if (!$list) {
			return array(
				'val' => false,
				'msg' => $L['no_product_to_provide_without_making_building']
			);
		}
		$classList = array();
		foreach ($list as $item) {
			$classList[] = $item['class'];
		}
		$class = array_rand($classList);
		$itemType = $classList[$class];
		// 载入制造对应的配置
		C('build/making');
		$className = array_search($itemType, $G['make_class_type_list']);
		$key = array_rand($G[$className]);
		$item = $G[$className][$key];
		$like_item = $item['item_id'];
		$off_time = $G['choose_time'] + $now;
		
		
		
		$DB->beginTransaction();
		
		// 排队区位置上的顾客信息移除
		$data = array(
			'now_guest'	=> 0,
			'state'		=> 0,
			'guest_lvl'	=> 0,
			'guest_mood'=> 0,
			'off_time'	=> 0,
			'last_reduce_mood_time'	=> 0,
		);
		$where = 'usqa_id='.$usqa['usqa_id'];
		$ret = $DB->update('user_shop_queue_area', $data, $where);
		
		
		// 垃圾数量 
		$sql = 'SELECT rubbish_num FROM user_shop WHERE uid='.$uid;
		$rubbish_num = $DB->getValue($sql);
		
		// 判断顾客心情值是否减少
		$intervalTime = $now - $usqa['last_reduce_mood_time'];
		$minites = floor($intervalTime/60);// 上次扣除心情到现在间隔的分钟数
		$reduceMoods = ($G['queue_reduce_mood'] + $rubbish_num) * $minites;
		$usqa['guest_mood'] -= $reduceMoods;
		if ($usqa['guest_mood'] < $G['guest_min_mood']) {
			$usqa['guest_mood'] = $G['guest_min_mood'];
		}
		
		
		//-- 销售区增加顾客信息
		$data = array(
			'now_guest'		=> $usqa['now_guest'],
			'guest_lvl'		=> $usqa['guest_lvl'],
			'guest_mood'	=> $usqa['guest_mood'],
			'need_item_type'=> $itemType,
			'now_item'		=> 0,
			'like_item'		=> $like_item,
			'quality'		=> 0,
			'main_mat_quality'=> 0,
			'need_service'	=> 0,
			'last_srv_time'	=> 0,
			'now_coin'		=> 0,
			'state'			=> 1,
			'off_time'		=> $off_time,
			'last_reduce_mood_time'	=> $now,
		);
		$where = 'ussa_id='.$ussa['ussa_id'];
		$ret = $DB->update('user_shop_sale_area', $data, $where);

		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array_merge($ussa, $data);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_depot_in', $str);
		}

		return $result;
	}
	
	/**
	 * 为顾客提供服务(开始销售)
	 * @param int $uid
	 * @param int $salePos
	 */
	public static function buy($uid, $salePos, $depot_id)
	{
		global $DB, $L, $G;
		
		$now = time();
	
		// 销售区位置上是否有挑选中的顾客
		$sql = 'SELECT * FROM user_shop_sale_area WHERE uid='.$uid.' and pos='.$salePos.' and state=1';
		$ussa = $DB->getValue($sql);
		if (!$ussa) {
			return array(
				'val' => false,
				'msg' => $L['shop_no_choose_guest']
			);
		}
		// 购买产品信息
		$sql = 'SELECT * FROM shop_depot WHERE depot_id='.$depot_id;
		$item = $DB->getValue($sql);
		
		// 物品类型不是顾客需要的
		if ($ussa['need_item_type'] != $item['item_type']) {
			return array(
				'val' => false,
				'msg' => $L['give_item_not_guest_request']
			);
		}
		
		// 已经过了挑选时间,顾客要离开 
		if ($ussa['off_time'] > 0 && $ussa['off_time'] <= $now) {
				// 有已经过期的顾客要清空
			$data = array(
				'now_guest'		=> 0,
				'state'			=> 0,
				'guest_lvl'		=> 0,
				'guest_mood'	=> 0,
				'need_item_type'=> 0,
				'now_item'		=> 0,
				'like_item'		=> 0,
				'quality'		=> 0,
				'main_mat_quality'=> 0,
				'need_service'	=> 0,
				'last_srv_time'	=> 0,
				'now_coin'		=> 0,
				'state'			=> 0,
				'off_time'		=> 0,
			);
			
			$where = 'ussa_id='.$ussa['ussa_id'];
			$ret = $DB->update('user_shop_sale_area', $data, $where);
			return array(
				'val' => false,
				'msg' => $L['shop_guest_pass_choose_time']
			);
		}
		
		$sql = 'SELECT COUNT(*) AS cnt FROM make_building WHERE uid='.$uid;
		$num = $DB->getValue($sql);
		if (!$num) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		// 垃圾数量 
		$sql = 'SELECT rubbish_num FROM user_shop WHERE uid='.$uid;
		$rubbish_num = $DB->getValue($sql);
		
		// 判断顾客心情值是否减少
		$intervalTime = $now - $ussa['last_reduce_mood_time'];
		$minites = floor($intervalTime/60);// 上次扣除心情到现在间隔的分钟数
		$reduceMoods = ($G['queue_reduce_mood'] + $rubbish_num) * $minites;
		$reduceTime = $minites*60 + $ussa['last_reduce_mood_time'];
		$ussa['last_reduce_mood_time'] = $reduceTime;
		$ussa['guest_mood'] -= $reduceMoods;
		if ($ussa['guest_mood'] < $G['guest_min_mood']) {
			$ussa['guest_mood'] = $G['guest_min_mood'];
		}
		
		C('shop/guest');
		
		// 是否高于/低于最低品质,对心情有加成/减少
		$min_quality = $G['guest_lvl_cfg'][$ussa['guest_lvl']]['min_quality'];
		if ($item['quality'] >= $min_quality) {
			$ratio = $item['quality']/$min_quality;
			// 超过最大的加成,只按最大加成计算 
			if ($ratio > (1+$G['quality_add_max_mood'])) {
				$ratio = 1 + $G['quality_add_max_mood'];
			}
			$ussa['guest_mood'] = round($ussa['guest_mood'] * $ratio);
		} else {
			$ratio = $item['quality']/$min_quality;
			// 低于最大的减成,只按最大减成计算 
			if ($ratio < (1-$G['quality_reduce_max_mood'])) {
				$ratio = 1 - $G['quality_reduce_max_mood'];
			}
			$ussa['guest_mood'] = round($ussa['guest_mood'] * $ratio);
		}
		
		// 制造产品类型数量速度加成
		$timeAddition = $G['shop_type_num_time_addition'][$num];
		$buyTime = $G['shop_sale_time_param'] * (100 - $timeAddition)/100;
		$off_time = $now + $buyTime;
		// 如果出售的商品是顾客特别喜欢的,则顾客的心情值会增加100点
		if ($item['item_id'] == $ussa['like_item']) {
			$guest_mood = $ussa['guest_mood'] + $G['like_item_add_mood'];
		} else {
			$guest_mood = $ussa['guest_mood'] + $G['not_like_item_add_mood'];
		}
//		if ($guest_mood < 0) {
//			$guest_mood = 0;
//		}
		
		$DB->beginTransaction();
		
		// 购买后,仓库的物品要删除
		$sql = 'DELETE from shop_depot WHERE depot_id='.$depot_id;
		$ret = $DB->exeSql($sql);
		
		//-- 顾客状态切换为购买
		if ($ret) {
			$data = array(
				'guest_mood'	=> $guest_mood,
				'now_item'		=> $item['item_id'],
				'quality'		=> $item['quality'],
				'main_mat_quality'=> $item['main_mat_quality'],
				'need_service'	=> 0,
				'last_srv_time'	=> $now,// 设为购买时间,方便计算第一次随机服务的时间
				'state'			=> 2,
				'off_time'		=> $off_time,
				'last_reduce_mood_time'	=> $reduceTime,
			);
			$where = 'ussa_id='.$ussa['ussa_id'];
			$ret = $DB->update('user_shop_sale_area', $data, $where);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$sql = 'SELECT * FROM user_shop_sale_area WHERE ussa_id='.$ussa['ussa_id'];
			$result['data'] = $DB->getValue($sql);
			$DB->commit();
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_depot_in', $str);
		}

		return $result;
	}
	
	/**
	 * 满足服务
	 * @param int $uid
	 * @param int $pos
	 * @param int $to_uid
	 */
	public static function giveService($uid, $pos, $to_uid=null)
	{
		global $DB, $L, $G;
		
		$now = time();
		
		if (empty($to_uid)) {
			$to_uid = $uid;
		} else {
			$to_uid = (int)$to_uid;
		}
		
		$sql = 'SELECT * FROM user_shop_sale_area WHERE uid='.$to_uid.' and pos='.(int)$pos;
		$ussa = $DB->getValue($sql);
		if (!$ussa || $ussa['need_service']==0) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		} elseif ($to_uid != $uid && !Friend::isFriend($uid, $to_uid)) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		$userInfo = User::read($uid);
		// 能量点不够
		if (!$userInfo['energy_point']) {
			return array(
				'val' => false,
				'msg' => $L['energy_point_not_enough']
			);
		}
		// 监狱里面不能操作
		if ($userInfo['in_prison']) {
			$sql = 'SELECT * FROM prison WHERE uid='.$uid;
			$prisonInfo = $DB->getValue($sql);
			if (!$prisonInfo['can_interactive']) {
				return array(
					'val' => false,
					'msg' => $L['cannot_help_give_service_in_prison']
				);
			}
		}
		
		$DB->beginTransaction();
		
		$service = $G['shop_service_list'][$ussa['need_service']];
		// 辅材
		$ret = true;
		$getSecMat = getRandResult($service['sec_mat_rate']);
		if ($getSecMat) {
			C('build/making');
			$className = array_search($ussa['need_item_type'], $G['make_class_type_list']);
			$sec_mat = array_rand($G[$className.'_sec_mat_item']);
			$data = array(
				'item_id' => $sec_mat,
				'item_type' => 51,//辅材类型
				'title' => $G[$className.'_sec_mat_item'][$sec_mat]['title'],
				'num' => 1,
				'stack' => 1,
				'quality' => $getSecMat,
			);
			$ret = Depot::in($uid, $data);
		}
		
		// 将金钱添加到用户数据中
		if ($ret) {
			$addCoin = rand($service['add_coin'][0], $service['add_coin'][1]);
			// 好友操作,金钱得到双倍,能量点减 1
			if ($uid != $to_uid) {
				$addCoin *= 2;
				$enery = ',energy_point=energy_point-1';
			} else {
				$enery = '';
			}
			$sql = 'UPDATE user SET coin=coin+'.$ussa['now_coin'].$enery.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		// 添加经验
//		if ($ret) {
//			$addExp = rand($service['add_exp'][0], $service['add_exp'][1]);
//			$ret = self::addExp($uid, $addExp);
//		}
		
		$data = array(
			'guest_mood'	=> $ussa['guest_mood'] + $service['add_mood'],
			'need_service'	=> 0,
			'last_srv_time'	=> $now
		);
		$where = 'ussa_id='.$ussa['ussa_id'];
		$ret = $DB->update('user_shop_sale_area', $data, $where);
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'add_coin' => $addCoin,
				'add_mood' => $service['add_mood'],
			);
			if ($getSecMat) {
				$result['data']['get_sec_mat'] = array(
					'item_id' => $sec_mat,
					'title' => $G[$className.'_sec_mat_item'][$sec_mat]['title'],
					'quality' => $getSecMat,
				);
			}
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_depot_in', $str);
		}

		return $result;
	}
	
	/**
	 * 结束购买
	 * @param int $uid
	 * @param int $pos
	 */
	public static function endBuy($uid, $pos)
	{
		global $DB, $L, $G;
		$now = time();
		
		$sql = 'SELECT * FROM user_shop_sale_area WHERE uid='.$uid.' and pos='.(int)$pos;
		$ussa = $DB->getValue($sql);
		if (!$ussa) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 该位置没有正在购买的顾客
		if ($ussa['state'] != 2) {
			return array(
				'val' => false,
				'msg' => $L['shop_not_exists_buying_guest']
			);
		}
		// 顾客购买时间未到
		if ($ussa['off_time'] > $now) {
			return array(
				'val' => false,
				'msg' => $L['shop_guest_buying_not_end']
			);
		}
		
		
		$sql = 'SELECT clean_val FROM user_shop WHERE uid='.$uid;
		$cleanVal = $DB->getValue($sql);
		// 清洁度影响
		$cleanEffect = $cleanVal/200+0.5;
		
		$DB->beginTransaction();
		
		C('shop/guest');
		// 销售获得经验
//		$exp = ($G['guest_lvl_cfg'][$ussa['guest_lvl']]['exp']
//				+ ($ussa['main_mat_quality'] * $G['shop_sale_exp_param']))
//				* (1 + $G['shop_sale_area_add_exp'][$ussa['lvl']]/100) 
//				* ($ussa['guest_mood']/$G['guest_max_mood']);
//		$ret = self::addExp($uid, $exp);

	
		// 最低品质要求
		if ($ussa['quality'] < $G['guest_lvl_cfg'][$ussa['guest_lvl']]['min_quality']) {
			$price = 0;
		} else {
			$price = $G['guest_lvl_cfg'][$ussa['guest_lvl']]['price_add'];
		}
		// 销售获得的金钱
		$price = round($G['shop_sale_price_param'] * $ussa['quality'] * $cleanEffect
						* (
							1 + $price + $G['shop_sale_area_add_price'][$ussa['lvl']]
						  )
				 );
		
		// 更新位置信息
		$data = array(
			'now_guest'		=> 0,
			'guest_lvl'		=> 0,
			'guest_mood'	=> 0,
			'need_item_type'=> 0,
			'now_item'		=> 0,
			'like_item'		=> 0,
			'quality'		=> 0,
			'main_mat_quality'=> 0,
			'need_service'	=> 0,
			'last_srv_time'	=> 0,
			'now_coin'		=> $price,
			'state'			=> 3,
			'off_time'		=> 0,
			'last_reduce_mood_time'	=> 0,
		);
		$where = 'ussa_id='.$ussa['ussa_id'];
		$ret = $DB->update('user_shop_sale_area', $data, $where);
		
		// 增加店铺完成购买顾客的心情总和和顾客总数
		if ($ret) {
			$sql = 'UPDATE user_shop SET ok_guest_mood=ok_guest_mood+'.$ussa['guest_mood']
					.', ok_guest_num=ok_guest_num+1 WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		// 增加店铺完成购买顾客的心情总和和顾客总数
		if ($ret) {
			$sql = 'UPDATE user_shop SET ok_guest_mood=ok_guest_mood+'.$ussa['guest_mood']
					.', ok_guest_num=ok_guest_num+1, '
					.' ok_item_quality=ok_item_quality+'.$ussa['quality'].' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array('now_coin' => $price);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_depot_in', $str);
		}

		return $result;
	}
	
	/**
	 * 获取销售得到的金钱
	 * @param int $uid
	 * @param int $pos
	 */
	public static function getCoin($uid, $pos, $target_uid=0)
	{
		global $DB, $L, $G;
		
		$now		= time();
		$today		= strtotime('today');
		$pos		= (int)$pos;
		$target_uid = (int)$target_uid;
		if (!$target_uid) {
			$target_uid = $uid;
		}
		
		$where = 'uid='.$target_uid.' and pos='.$pos;
		$sql = 'SELECT ussa_id,state,now_coin FROM user_shop_sale_area WHERE '.$where;
		$ussa = $DB->getValue($sql);
		
		if ($ussa['state']!=3) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		// 目标店铺不是自己的,判断是否好友店铺
		if ($uid != $target_uid && !Friend::isFriend($uid, $target_uid)) {
			return array(
				'val' => false,
				'msg' => $L['cannot_get_coin_from_not_friend']
			);
		}
		
		$sql = 'SELECT lvl,remain_get_coin_times,last_get_coin_time,energy_point,in_prison FROM user WHERE uid='.$uid;
		$userInfo = $DB->getValue($sql);
		// 好友操作
		if ($uid != $target_uid) {
			// 帮好友收取金钱的次数是否达到上限
			if (!$userInfo['remain_get_coin_times'] && $userInfo['last_get_coin_time'] > $today) {
				return array(
					'val' => false,
					'msg' => $L['help_get_coin_times_max_today']
				);
			}
			// 能量点不够
			if (!$userInfo['energy_point']) {
				return array(
					'val' => false,
					'msg' => $L['energy_point_not_enough']
				);
			}
			// 监狱里面不能操作
			if ($userInfo['in_prison']) {
				$sql = 'SELECT * FROM prison WHERE uid='.$uid;
				$prisonInfo = $DB->getValue($sql);
				if (!$prisonInfo['can_interactive']) {
					return array(
						'val' => false,
						'msg' => $L['cannot_help_get_coin_in_prison']
					);
				}
			}
			$sql = 'SELECT lvl,remain_get_coin_times FROM user WHERE uid='.$target_uid;
			$targetInfo = $DB->getValue($sql);
		}
		
		$DB->beginTransaction();
		
		// 将金钱添加到店主用户数据中
		$sql = 'UPDATE user SET coin=coin+'.$ussa['now_coin'].' WHERE uid='.$target_uid;
		$ret = $DB->exeSql($sql);
		
		if ($ret) {
			$data = array(
				'now_coin'	=> 0,
				'state'		=> 0
			);
			$ret = $DB->update('user_shop_sale_area', $data, 'ussa_id='.$ussa['ussa_id']);
		}
		
		// 帮好友收取金钱,自己也可以得到奖励,同时更新帮好友收到金钱次数(玩家等级必须大于店主等级-15)
		if ($ret && $uid != $target_uid && $userInfo['lvl'] > ($targetInfo['lvl']-15)) {
			if ($userInfo['lvl'] >= $targetInfo['lvl']) {
				$getCoin = round($ussa['now_coin'] * 0.1);
			} else if (($targetInfo['lvl'] - $userInfo['lvl']) >= 15) {
				$getCoin = 0;
			} else {
				$getCoin = round(
									$ussa['now_coin'] * (15 - ($targetInfo['lvl'] - $userInfo['lvl']))
									* (1/150)
							);
			}
			// 更新今天帮好友收取金钱的次数和时间
			if ($userInfo['last_get_coin_time'] > $today) {
				$sql = 'UPDATE user SET coin=coin+'.$getCoin
						.', remain_get_coin_times=remain_get_coin_times-1, '
						.' last_get_coin_time='.$now.',energy_point=energy_point-1'
						.' WHERE uid='.$uid;
			} else {// 今天第一次帮好友收取金钱
				$remain_times = $G['help_get_coin_times_per_day'] - 1;
				$sql = 'UPDATE user SET coin=coin+'.$getCoin
						.', remain_get_coin_times='.$remain_times.', '
						.' last_get_coin_time='.$now.',energy_point=energy_point-1'
						.' WHERE uid='.$uid;
			}
//			echo $sql;
			$ret = $DB->exeSql($sql);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'get_coin' => $getCoin
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_get_coin', $str);
		}

		return $result;
	}
	
	/**
	 * 获取销售区的空位列表
	 * @param int $uid
	 * @param int $to_uid 获取他人的列表
	 */
	public static function getSaleList($uid, $to_uid=null)
	{
		global $DB, $L, $G;
		$now = time();

		$to_uid = (int)$to_uid;
		if ($to_uid) {
			$uid = $to_uid;
		}
		
		// 判断是否产生垃圾
		self::randRubbish($uid);
		
		$sql = 'SELECT * FROM user_shop_sale_area WHERE uid='.$uid;
		$tmp = $DB->getList($sql);
		if (!$tmp) {
			return array(
				'val'	=> false,
				'msg'	=> $L['invalid_request']
			);
		}
		
		
		// 垃圾数量 
		$sql = 'SELECT sale_space,rubbish_num,last_rand_rubbish_time FROM user_shop WHERE uid='.$uid;
		$shopInfo = $DB->getValue($sql);
		if (!$shopInfo) {
			return array(
				'val'	=> false,
				'msg'	=> $L['invalid_request']
			);
		}
		$rubbish_num = $shopInfo['rubbish_num'];
		
		$updateIds = array();
		$updateSql = '';
		$list = array();
		foreach ($tmp as $k=>$v) {
			if ($v['state'] == 0) {
				$list[$v['pos']] = $v;
				continue;
			}
			if ($v['off_time'] > 0 && $v['off_time'] <= $now) {
				
				// 正在购买状态的调用结束购买方法
				if ($v['state'] == 2) {
					$return = self::endBuy($uid, $v['pos']);
				} else {
					$updateIds[] = $v['ussa_id'];
				}
				$list[$v['pos']] = $v;
				continue;
			}
			
			// 是否产生服务
			if ($v['state'] == 2 && $v['need_service'] == 0) {
				$intervalTime = $now - $v['last_srv_time'];
				$newTime = rand($G['service_wait_time'][0], $G['service_wait_time'][1]);
				if ($intervalTime >= $newTime) {
					// 生成一个随机服务
					$service = array_rand($G['shop_service_list']);
					$data = array(
						'need_service'	=> $service,
						'last_srv_time'	=> $v['last_srv_time'] + $newTime,
					);
					$where = 'ussa_id='.$v['ussa_id'];
					$DB->update('user_shop_sale_area', $data, $where);
				}
			}
			
			// 判断顾客心情值是否减少
			if ($v['state'] == 1) {
				$intervalTime = $now - $v['last_reduce_mood_time'];
				$reduceUnit = floor($intervalTime/120);//扣除次数,每两分钟计算一次
				$reduceMoods = ($G['queue_reduce_mood'] + $rubbish_num) * $reduceUnit;
				$reduceTime = $reduceTimes*120 + $v['last_reduce_mood_time'];
				$v['last_reduce_mood_time'] = $reduceTime;
				if (($v['guest_mood']-$G['guest_min_mood']) > $reduceMoods) {
					$v['guest_mood'] -= $reduceMoods;
				} else {
					$v['guest_mood'] = $G['guest_min_mood'];
				}
				// 不足一分钟,不更新
				if ($minites) {
					$updateSql .= 'UPDATE user_shop_sale_area SET last_reduce_mood_time='.$reduceTime
							.', guest_mood='.$v['guest_mood']
							.' WHERE ussa_id='.$v['ussa_id'].';';
				}
			}
			
			$list[$v['pos']] = $v;
		}
		
		$DB->beginTransaction();
		$ret = true;
		
		if ($updateSql != '') {
			$ret = $DB->exeSql($updateSql);
			if ($ret !==false) {
				$ret = true;
			}
		}
		
		if ($ret && count($updateIds) > 0) {
			$data = array(
				'now_guest'			=> 0,
				'guest_lvl'			=> 0,
				'guest_mood'		=> 0,
				'need_item_type'	=> 0,
				'now_item'			=> 0,
				'quality'			=> 0,
				'main_mat_quality'	=> 0,
				'need_service'		=> 0,
				'last_srv_time'		=> 0,
				'now_coin'			=> 0,
				'state'				=> 0,
				'off_time'			=> 0,
			);
			$where = 'ussa_id in ('.join(',', $updateIds).')';
			$ret = $DB->update('user_shop_sale_area', $data, $where);
			if ($ret !==false) {
				$ret = true;
			}
		}
		
		$sql = 'SELECT * FROM user_shop_sale_area WHERE uid='.$uid;
		$tmp = $DB->getList($sql);
		$list = array();
		$nextRefreshTime = $now + 3600;
		$minOffTime = $nextRefreshTime;
		foreach ($tmp as $k=>$v) {
			$list[$v['pos']] = $v;
			if ($v['off_time'] > 0) {
				$minOffTime = min($minOffTime, $v['off_time']);
			}
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			// 可以产生垃圾,下次刷新时间
			if ($shopInfo['rubbish_num'] < $shopInfo['sale_space']) {
				$nextRefreshTime = min($nextRefreshTime, strtotime(date('Y-m-d H:0:0').'+1 hours'));
			}
			$nextRefreshTime = min($minOffTime, $nextRefreshTime);
			$result['data'] = array(
				'list' => $list,
				'next_refresh_time' => $nextRefreshTime
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('get_sale_list', $str);
		}
		
		return $result;
	}
	
	/**
	 * 获取店铺仓库当前总格子数
	 * @param int $uid
	 */
	public static function getDepotSpaceNum($uid)
	{
		global $DB;
		$sql = 'SELECT depot_space FROM user_shop WHERE uid='.$uid;
		return $DB->getValue($sql);
	}
	
	/**
	 * 指定玩家的仓库剩余格子
	 * @param int $uid
	 */
	public static function getDepotFreeSpace($uid)
	{
		global $DB, $L, $G;
		$sql = 'SELECT depot_space FROM user_shop WHERE uid='.$uid;
		$depot_space = $DB->getValue($sql);
		
		$sql = 'SELECT count(*) as cnt FROM shop_depot WHERE uid='.$uid;
		$count = $DB->getValue($sql);
		
		if ($count >= $depot_space) {
			return 0;
		} else {
			return ($depot_space - $count);
		}
	}
	
	/**
	 * 物品进入店铺仓库
	 * @param int $uid
	 * @param array $data
	 */
	public static function depotIn($uid, $data)
	{
		global $DB, $L, $G;
		
		$freeSpace = self::getDepotFreeSpace($uid);
		
		if (!$freeSpace) {
			return array(
				'val' => false,
				'msg' => $L['shop_depot_havenot_free_space']
			);
		}

		$itemId		= (int)$data['item_id'];
		$itemType	= (int)$data['item_type'];
		$num		= (int)$data['num'];
		$quality	= (int)$data['quality'];
		$mainMatQuality	= isset($data['main_mat_quality'])
						? (int)$data['main_mat_quality']
						: 0;
		$lvl = isset($data['lvl']) ? $data['lvl'] : 0;
	
		if (isset($data['title'])) {
			$title = $data['title'];
		} else {
			$titems   = C('item/item_list');
			$itemInfo = $titems[$itemId];
			$title = $itemInfo['title'];
		}
		
		
		$data = array(
			'uid'     => $uid,
			'item_id' => $itemId,
			'item_type' => $itemType,
			'title'   => $title,
			'num'     => $num,
			'stack'   => 0,
			'quality' => $quality,
			'main_mat_quality' => $mainMatQuality,
			'lvl'	=> $lvl
		);
		$ret = $DB->insert('shop_depot', $data);

		$result['val'] = (boolean)$ret;
		if ($ret) {
			$result['data'] = array(
				'depot_id' => $ret
			);
			$result['msg'] = $L['Success'];
		} else {
			$result['msg'] = $L['Failure_Insert'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_depot_in', $str);
		}

		return $result;
	}
	
	/**
	 * 读取用户仓库物品列表
	 * @param int $u_id 用户ID
	 * @param int $type 仓库物品类型
	 * @param int $item_id 仓库物品ID(小类型)
	 */
	public static function getDepotList($uid, $type=0, $item_id=0)
	{
		global $DB, $L, $G;
		
		$type = (int)$type;
		$item_id = (int)$item_id;
		
		$list = array();
		$where = 'uid='.(int)$uid;
		if ($type) {
			$where .= ' AND item_type='.$type;
		}
		if ($item_id) {
			$where .= ' AND item_id='.$item_id;
		}
		$curNum = $DB->getCount('shop_depot', $where);
		//$maxNum = $DB->getValue('SELECT depot_max_capacity FROM user WHERE uid='.$uid);
		$total = $DB->getCount('shop_depot', $where);
		$sql = 'SELECT * FROM shop_depot WHERE '.$where;
		$arr = $DB->getList($sql);
		if (false === $arr) {
			return array(
				'val' => false,
				'msg' => $L['Failure']
			);
		}
		foreach ($arr as $val) {
			$list[] = $val;
		}
		
		return array(
			'val'  => true,
			'data' => array(
				'list' => $list,
				'free_grid' => self::getDepotFreeSpace($uid),
				'max_grid'  => self::getDepotSpaceNum($uid)
			)
		);
	}
	
	/**
	 * 为店铺增加经验
	 * @param int $uid
	 * @param int $addExp
	 */
//	public static function addExp($uid, $addExp)
//	{
//		global $DB, $L, $G;
//		
//		$sql = 'SELECT shop_lvl,exp FROM user_shop WHERE uid='.$uid;
//		$shop = $DB->getValue($sql);
//		
//		$lvl = $shop['shop_lvl'];
//		$exp = $shop['exp'] + $addExp;
//		
//		$expList = self::$cfg;
//		end($expList);
//		$maxLvl = key($expList);// 玩家可以升级的最高等级
//		$maxExp = $expList[$lvl];
//		
//		// 满级且经验值超过最高经验值,将经验值设为最高经验值
//		if ($lvl == $maxLvl && $exp > $maxExp) {
//			$exp = $maxExp;
//		} else if ($exp >= $maxExp) { // 需要升级
//			$exp -= $maxExp;
//			$lvl++;
//			for ($i=$lvl; $i<=$maxLvl; $i++) {
//				// 剩余熟练度不足以再升级
//				if ($exp < $expList[$lvl]) {
//					break;
//				} else {// 继续升级
//					$exp -= $expList[$lvl];
//					$lvl++;
//				}
//			}
//		}
//		
//		$data = array(
//			'shop_lvl' => $lvl,
//			'exp' => $exp
//		);
//		$ret = $DB->update('user_shop', $data, 'shop_id='.$shop['shop_id']);
//		// 同时更新用户表的数据
//		$data = array(
//			'shop_lvl' => $lvl,
//			'shop_exp' => $exp
//		);
//		$ret = $DB->update('user', $data, 'uid='.$uid);
//		
//		return $ret;
//	}
	
	/**
	 * 拉拢好友顾客
	 * @param int $uid
	 * @param int $friend_id 被拉拢的好友ID
	 * @param int $queuePos 被拉拢排队区的顾客位置
	 */
	public static function lureGuest($uid, $friend_id, $queuePos)
	{
		global $DB, $L, $G;
		
		$now = time();
		$today		= strtotime('today');
		$friend_id = (int)$friend_id;
		$queuePos = (int)$queuePos;
		
		if (!Friend::isFriend($uid, $friend_id)) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 将增加的顾客添加到自己的排队空位
		$sql = 'SELECT usqa_id FROM user_shop_queue_area WHERE uid='.$uid.' AND state=0';
		$myUsqa = $DB->getValue($sql);
		if (!$myUsqa) {
			// 自己排队区没有空位
			return array(
				'val' => false,
				'msg' => $L['no_queue_pos_to_grab']
			);
		}
		
		$userInfo = User::read($uid);
		// 能量点不够
		if (!$userInfo['energy_point']) {
			return array(
				'val' => false,
				'msg' => $L['energy_point_not_enough']
			);
		}
		// 监狱里面不能操作
		if ($userInfo['in_prison']) {
			$sql = 'SELECT * FROM prison WHERE uid='.$uid;
			$prisonInfo = $DB->getValue($sql);
			if (!$prisonInfo['can_interactive']) {
				return array(
					'val' => false,
					'msg' => $L['cannot_lure_in_prison']
				);
			}
		}
		
		$needCoin = $G['lure_guest_need_coin'];
		// 金钱不足
		if ($needCoin > $userInfo['coin']) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		// 当日拉拢次数已满
		if (!$userInfo['remain_lure_guest_times'] && $userInfo['last_lure_guest_time'] >= $today) {
			return array(
				'val' => false,
				'msg' => $L['lure_guest_times_max_today']
			);
		}
		
		$sql = 'SELECT * FROM user_shop_queue_area WHERE uid='.$friend_id.' AND pos='.$queuePos;
		$info = $DB->getValue($sql);
		if (!$info) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 不存在顾客
		if (!$info['now_guest']) {
			return array(
				'val' => false,
				'msg' => $L['no_guest_to_lure']
			);
		}
		
		// 垃圾数量 
		$sql = 'SELECT rubbish_num FROM user_shop WHERE uid='.$uid;
		$rubbish_num = $DB->getValue($sql);
	
		// 顾客心情值要减少
		$intervalTime = $now - $info['last_reduce_mood_time'];
		$minites = floor($intervalTime/60);// 上次扣除心情到现在间隔的分钟数
		// 减少心情数要考虑垃圾数量
		$reduceMoods = ($G['queue_reduce_mood'] + $rubbish_num) * $minites;
		$reduceTime = $minites*60 + $info['last_reduce_mood_time'];
		$info['last_reduce_mood_time'] = $reduceTime;
		if ($info['guest_mood'] > $reduceMoods) {
			$info['guest_mood'] -= $reduceMoods;
		} else {
			$info['guest_mood'] = 0;
		}
			
		// 顾客心情值高于可被抢占的值
		if ($info['guest_mood'] > $G['can_be_grabbed_guest_mood']) {
			return array(
				'val' => false,
				'msg' => $L['guest_mood_cannot_be_grabbed']
			);
		}
		
		$DB->beginTransaction();
		
		// 清空顾客信息
		$data = array(
			'now_guest'	=> 0,
			'state'		=> 0,
			'guest_lvl'	=> 0,
			'guest_mood'=> 0,
			'off_time'	=> 0,
		);
		$where = 'usqa_id='.$info['usqa_id'];
		$ret = $DB->update('user_shop_queue_area', $data, $where);
		
		// 顾客已经过期
		if ($info['off_time'] < $now) {
			if ($ret) {
				$DB->commit();
			} else {
				$DB->rollBack();
			}
			return array(
				'val' => false,
				'msg' => $L['no_guest_to_lure']
			);
		}
		
		// 更新拉拢顾客次数时间信息,金钱
		if ($ret) {
			$sql = 'UPDATE user SET coin=coin-'.$needCoin
					.', remain_lure_guest_times=remain_lure_guest_times-1, '
					.'energy_point=energy_point-1,'
					.' last_lure_guest_time='.$now.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		if ($ret) {
			$data = array(
				'now_guest'	=> $info['now_guest'],
				'state'		=> 1,
				'guest_lvl'	=> $info['guest_lvl'],
				'guest_mood'=> $info['guest_mood'] + $G['grab_guest_add_mood'],
				'off_time'	=> $now + $G['queue_wait_time'],
			);
			$where = 'usqa_id='.$myUsqa;
			$ret = $DB->update('user_shop_queue_area', $data, $where);
//			var_export($data);
//			var_export($myUsqa);
//			var_dump($ret);
		}
		
//		exit;
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				
			);
			$result['msg'] = $L['Success'];
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_lure_guest', $str);
		}

		return $result;
	}
	
	/**
	 * 随机产生垃圾
	 * @param int $uid
	 * @param array $ussa 要产生垃圾的空位信息
	 */
	private static function randRubbish($uid)
	{
		global $DB, $L, $G;
		
		$now = time();
		$nowHourTime = strtotime(date('Y-m-d H:0:0'));
		$nowHour = date('H');
		
		// 凌晨1点到7点整点时间不产生垃圾
		if ($nowHour > 0 && $nowHour <=8) {
			return false;
		}
		
		$sql = 'SELECT sale_space,rubbish_num,create_time,last_rand_rubbish_time FROM user_shop WHERE uid='.$uid;
		$record = $DB->getValue($sql);
		
		// 本次整点已产生垃圾(创建店铺后要到下一个整点时间)
		if ($nowHourTime <= $record['last_rand_rubbish_time']) {
			return false;
		}
		
		// 所有空位全是垃圾
		if ($record['rubbish_num'] == $record['sale_space']) {
			return false;
		}
		
		//机率转化100以内整数,所以公式/10*100,转成*10
		$rate = (10-$record['rubbish_num'])*10;
		$getRubbish = getRandResult($rate);
		
		$DB->beginTransaction();
		
		$ret = false;
		
		if ($getRubbish) {
			$sql = 'SELECT ussa_id FROM user_shop_sale_area WHERE uid='.$uid
					.' AND rubbish=0 ORDER BY RAND()';
			$ussa_id = $DB->getValue($sql);
			if ($ussa_id) {
				$data = array(
					'rubbish' => 1,
				);
				$ret = $DB->update('user_shop_sale_area', $data, 'ussa_id='.$ussa_id);
				if (false !== $ret) {
					if (!$ret) {
						Log::save('shop_rand_rubbish', 'UPDATE user_shop_sale_area SET rubbish=1 WHERE ussa_id='.$ussa_id);
					}
					$ret = true;
				}
			}
		}
		
		// 更新店铺的垃圾数量和产生时间,减少清洁度
		if ($ret) {
			$sql = 'UPDATE user_shop SET clean_val=clean_val-'.$G['clean_val_per_rubbish']
					.',rubbish_num=rubbish_num+1, last_rand_rubbish_time='.$nowHourTime
					.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
			if (false !== $ret) {
				$ret = true;
			}
		}
		
		if ($ret) {
			$DB->commit();
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors.$sql, true);
			// 记录错误日志
			Log::save('shop_rand_rubbish', $str);
		}
		
		return $ret;
	}
	
	/**
	 * 清洁
	 * @param int $uid
	 * @param int $ussa_id
	 */
	public static function clearRubbish($uid, $ussa_id)
	{
		global $DB, $L, $G;
		
		$now		= time();
		$today		= strtotime('today');
		$nowHourTime = strtotime(date('Y-m-d H:0:0'));
		$ussa_id	= (int)$ussa_id;
		
		$sql = 'SELECT * FROM user_shop_sale_area WHERE ussa_id='.$ussa_id;
		$ussa = $DB->getValue($sql);
		
		if (!$ussa) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		// 没有垃圾,不需要清洁
		if (!$ussa['rubbish']) {
			return array(
				'val' => false,
				'msg' => $L['no_rubbish_to_clear']
			);
		}
		
		// 不是好友，不能清除别人的
		if ($ussa['uid'] != $uid && !Friend::isFriend($uid, $ussa['uid'])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		// 清洁自己店铺,要消耗金钱,先判断是否足够
		if ($ussa['uid'] == $uid) {
			// 金钱是否足够
			$needCoin = $G['clean_rubbish_need_coin'];
			$sql = 'SELECT coin FROM user WHERE uid='.$uid;
			$coin = $DB->getValue($sql);
			if ($needCoin > $coin) {
				return array(
					'val' => false,
					'msg' => $L['coin_not_enough']
				);
			}
		} else {// 当天给好友清洁店铺的次数是否达到上限
			$sql = 'SELECT remain_clear_shop_times,last_clear_shop_time FROM user WHERE uid='.$uid;
			$userInfo = $DB->getValue($sql);
			if (!$userInfo['remain_clear_shop_times'] && $userInfo['last_clear_shop_time']>$today) {
				return array(
					'val' => false,
					'msg' => $L['help_clear_rubbish_times_max_today']
				);
			}
			$userInfo = User::read($uid, 'lvl,energy_point,in_prison');
			// 能量点不够
			if (!$userInfo['energy_point']) {
				return array(
					'val' => false,
					'msg' => $L['energy_point_not_enough']
				);
			}
			// 监狱里面不能操作
			if ($userInfo['in_prison']) {
				$sql = 'SELECT * FROM prison WHERE uid='.$uid;
				$prisonInfo = $DB->getValue($sql);
				if (!$prisonInfo['can_interactive']) {
					return array(
						'val' => false,
						'msg' => $L['cannot_help_clean_in_prison']
					);
				}
			}
		}
		
		$DB->beginTransaction();
		
		$data = array(
			'rubbish' => 0,
		);
		$ret = $DB->update('user_shop_sale_area', $data, 'ussa_id='.$ussa['ussa_id']);
		
		// 给自己店铺清洁消耗金钱
		if ($ret && $ussa['uid'] == $uid) {
			$sql = 'UPDATE user SET coin=coin-'.$needCoin.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
			if (false !== $ret) {
				$ret = true;
			}
		} elseif ($ret && $ussa['uid'] != $uid) {// 给好友店铺清洁,记录清洁次数
			if ($userInfo['last_clear_shop_time']>=$today) {
				$sql = 'UPDATE user SET remain_clear_shop_times=remain_clear_shop_times-1,'
						.'last_clear_shop_time='.$now.',energy_point=energy_point-1 WHERE uid='.$uid;
			} else {
				$remain_times = $G['help_friend_clean_rubbish_max_times'] - 1;
				$sql = 'UPDATE user SET remain_clear_shop_times='.$remain_times.','
						.'last_clear_shop_time='.$now.',energy_point=energy_point-1 WHERE uid='.$uid;
			}
			$ret = $DB->exeSql($sql);
			if (false !== $ret) {
				$ret = true;
			}
		}
		
		// 增加清洁度,减少垃圾数量,更新上次随机生成垃圾的时间为本次整点
		if ($ret) {
			$sql = 'UPDATE user_shop SET clean_val=clean_val+'.$G['clean_val_per_rubbish'].', '
					.' rubbish_num=rubbish_num-1, last_rand_rubbish_time='.$nowHourTime.' WHERE uid='.$ussa['uid'];
			$ret = $DB->exeSql($sql);
			if (false !== $ret) {
				$ret = true;
			}
		}
		
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'add_clean_val' => $G['clean_val_per_rubbish'],
				'use_coin'		=> $needCoin
			);
			$result['msg'] = $L['Success'];
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_clear_rubbish', $str);
		}

		return $result;
	}
	
	/**
	 * 店铺留言
	 * @param int $uid 当前用户ID
	 * @param int $shop_id 被留言的店铺ID
	 * @param int $content 留言内容
	 */
	public static function leaveMessage($uid, $shop_id, $content)
	{
		global $DB, $L, $G;
		
		$shop_id = (int)$shop_id;
		$today = strtotime('today');
		
		// 当日在同一店铺留言次数是否达到上限
		$sql = 'SELECT COUNT(*) FROM shop_message WHERE uid='.$uid.' AND shop_id='.$shop_id
				.' AND post_time>='.$today;
		$cnt = $DB->getValue($sql);
		if ($cnt >= $G['max_leave_msg_in_same_shop']) {
			return array(
				'val' => false,
				'msg' => $L['you_had_leave_max_msg_in_same_shop']
			);
		}
		
		$sql = 'SELECT uid FROM user_shop WHERE shop_id='.$shop_id;
		$toUid = $DB->getValue($sql);
		
		$DB->beginTransaction();
		
		$data = array(
			'uid'		=> $uid,
			'shop_id'	=> $shop_id,
			'to_uid'	=> $toUid,
			'content'	=> $content,
			'post_time'	=> time(),
		);
		$ret = $DB->insert('shop_message', $data);
		
		
		$result['val'] = (bool)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				
			);
			$result['msg'] = $L['Success'];
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure_Update'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('shop_leave_message', $str);
		}

		return $result;
	}
	
	
}